package modelo.reglas.engine;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import modelo.Oferta;
import modelo.OrdenDeCompra;
import modelo.Producto;
import modelo.query.InvalidQueryException;
import modelo.reglas.composite.inner.GroupSpecification;
import util.ProductUtils;
import util.QueryUtils;

/*
 * Clase utilitaria para la venta
 */
public class Seller {

	public static BigDecimal obtainCuponTotalOfBuyOrder(List<Oferta> availableOffers, OrdenDeCompra ordenCompra) throws InvalidQueryException {

		Map<Oferta, List<Producto>> applingOffersToBuyOrder = obtainApplingOffersToBuyOrder(availableOffers, ordenCompra);

		BigDecimal totalPrecioSinDescuento = ProductUtils.getTotalPriceWithoutDiscount(applingOffersToBuyOrder);
		BigDecimal totalPrecioConDescuento = ProductUtils.getTotalPrice(applingOffersToBuyOrder);

		BigDecimal totalCupon = totalPrecioSinDescuento.subtract(totalPrecioConDescuento);

		return totalCupon;
	}

	public static Map<Oferta, List<Producto>> obtainApplingOffersToBuyOrder(List<Oferta> availableOffers, OrdenDeCompra ordenCompra)
			throws InvalidQueryException {

		Map<Oferta, List<Producto>> ofertasQueAplican = new HashMap<Oferta, List<Producto>>();

		List<Producto> productosClonados = new ArrayList<Producto>(ordenCompra.getProductos());
		for (Oferta ofertaAnalizado : availableOffers) {

			GroupSpecification<Producto> materializeQuery = QueryUtils.materializeQuery(ofertaAnalizado);
			if (materializeQuery.isSatisfiedBy(productosClonados)) {
				ofertasQueAplican.put(ofertaAnalizado, removerPrimerAparicion(productosClonados, materializeQuery.getElementosQueCumplen()));
			}
		}

		return ofertasQueAplican;
	}

	private static List<Producto> removerPrimerAparicion(List<Producto> productosALimpiar, List<Producto> produBuscados) {

		List<Producto> productosRemovidos = new ArrayList<Producto>();

		for (Producto productoBuscado : produBuscados) {

			for (Producto productoCheckeado : productosALimpiar) {
				if (productoCheckeado.compareTo(productoBuscado) == 0) {
					productosALimpiar.remove(productoCheckeado);

					productosRemovidos.add(productoCheckeado);
					break;
				}
			}
		}

		return productosRemovidos;
	}
}
